﻿using System;
using System.Collections;
using AcademicPlanner.Data.Entities;
using NHibernate.Tool.hbm2ddl;
using NHibernate;

namespace AcademicPlanner.Data.Repositories
{
	/// <summary>
	/// AccountEntityRepository serves as the repository for <c>AccountEntity</c>s.
	/// </summary>
	/// <version>1.0</version>
	/// <since>1.0</since>
	public class AccountEntityRepository : EntityRepository<AccountEntity>
    {
		private AccountEntityRepository() 
		{ 
			namedQueriesPrefix = "AccountEntity";
		}

		private class InstanceHolder 
		{
			internal static AccountEntityRepository INSTANCE = new AccountEntityRepository(); 
		}


		/// <summary>
		/// The the single instance of AccountEntityRepository.
		/// </summary>
		/// <returns>The single instance of AccountEntityRepository.</returns>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public static AccountEntityRepository GetInstance()
		{ 
			return InstanceHolder.INSTANCE; 
		}


		/// <summary>
		/// Creates a new <c>AccountEntity</c> and sets its default values.
		/// </summary>
		/// <returns>The newly created <c>AccountEntity</c>.</returns>
		/// <seealso cref="M:AcademicPlanner.Data.Entities.AccountEntity.SetDefaults"/>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public AccountEntity GetNew()
		{
			var rEnt = new AccountEntity();
			rEnt.SetDefaults();
			return rEnt;
		}

		/// <summary>
		/// Finds the <c>AccountEntity</c> whose <c>UserEntity</c> has the given username from
		/// the persistence layer.
		/// </summary>
		/// <param name="pUserName">The username.</param>
		/// <returns>The <c>AccountEntity</c> or <c>null</c>.</returns>
		/// <exception cref="T:AcademicPlanner.Data.DataException">
		/// Thrown with an error code of <c>DataErrorCode.QUERY_ACCOUNT_ENTITY_BY_USER_USERNAME_FAILED</c>
		/// when an error is reported by NHibernate. The <c>HibernateException</c> is
		/// accessible via the <c>InnerException</c> property.
		/// </exception>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public AccountEntity FindByUserName(string pUserName)
		{
			AccountEntity rEnt = null;
			IQuery vQuery = GetQuery("by.user.username");
			IList vEnts;

			try
			{
				vQuery.SetString("username", pUserName);
				vQuery.SetMaxResults(1);
				vEnts = vQuery.List();
			}
			catch (HibernateException vHx)
			{
				var vDx = new DataException(DataErrorCode.QUERY_ACCOUNT_ENTITY_BY_USER_USERNAME_FAILED, vHx);
				throw vDx;
			}

			if (vEnts.Count > 0)
				rEnt = (AccountEntity)vEnts[0];

			return rEnt;
		}
	}
}
